#ifndef TCPSERVER
#define TCPSERVER

// 把所有的模块整合起来，通过实例化对象就可以创建一个服务器实例
// 不需要使用者在繁琐的创建各种对象，手动管理事件
#include "Acceptor.h"
#include "Connection.h"
#include "LoopThreadPool.h"
#include <signal.h>
/**
 * 我们需要做的：
 *      1. 设置从属线程池的线程数量
 *      2. 启动服务器(_baseloop->Start())
 *      3. 设置各种回调函数(连接建立完成，消息，关闭，任意)，用户设置回调函数，tcpserver设置给新连接
 *      4. 是否启动非活跃连接超时销毁功能
 *      5. 添加定时任务功能
 */
/**
 * 流程：
 *      1. 在tcpserver中实例化Acceptor和EventLoop对象
 *      2. 把Acceptor挂到EventLoop上进行事件监控
 *      3. 如果有Acceptor对象就绪了可读事件，通过读事件回调函数获取新连接
 *      4. 对新连接，建立一个Connection进行管理
 *      5. 对连接对于的Connection设置各种回调函数
 */
class TcpServer
{
private:
    using Functor = std::function<void()>;
    using ConnectedCallBack = std::function<void(const PtrConnection &)>;
    using MessageCallBack = std::function<void(const PtrConnection &, Buffer *)>;
    using RandomEventCallBack = std::function<void(const PtrConnection &)>;
    using ClosedCallBack = std::function<void(const PtrConnection &)>;

private:
    // 为新连接构造一个新的Connection管理
    void NewConnection(int fd);
    // 从服务器移除连接
    void RemoveConnection(const PtrConnection &);
    void RemoveConnectionInLoop(const PtrConnection &);
    void RunAfterInLoop(const Functor &, uint32_t delay);

public:
    // TcpServer(EventLoop *, uint16_t);
    TcpServer(uint16_t); // 新增：自动创建 EventLoop 的构造函数
    ~TcpServer();
    void Start();
    void setThreadCount(uint32_t);
    void EnableInactiveRelease(uint32_t);
    // 超时执行的任务
    void RunAfter(const Functor &, uint32_t delay);
    void SetConnectedCallBack(const ConnectedCallBack &);
    void SetMessageCallBack(const MessageCallBack &);
    void SetRandomEventCallBack(const RandomEventCallBack &);
    void SetClosedCallBack(const ClosedCallBack &);
    void SetServerClosedCallBack(const ClosedCallBack &cl_cb);

private:
    uint16_t _port;
    uint64_t _nextid;  // 自增的唯一id
    uint32_t _timeout; // 非活跃连接的超时释放时间
    EventLoop *_baseloop;
    bool _own_loop;                                    // 标记是否拥有 EventLoop 的所有权
    bool _enable_inactive_release;                     // 对套接字上的事件的管理
    Acceptor _acceptor;                                // 创建监听套接字
    std::unordered_map<uint64_t, PtrConnection> _conn; // 对所有的连接进行管理
    LoopThreadPool _threads_pool;                      // 主从Reactor，对事件的处理和监控

    ConnectedCallBack _conn_cb;      // 建立连接回调
    RandomEventCallBack _rand_ev_cb; // 任意事件的回调
    ClosedCallBack _close_cb;        // 连接关闭的回调
    MessageCallBack _mess_cb;        // 数据处理回调
    ClosedCallBack _server_close_cb; // 服务器内部连接关闭的回调
};

class NetWork
{
public:
    NetWork()
    {
        // 程序退出后，继续发消息会导致程序异常，发送SIGPIPE信号，这里是忽略这个信号
        DBG_LOG("SIGPIPE INIT");
        signal(SIGPIPE, SIG_IGN);
    }
};
#endif